<!doctype html>
<html lang="zh-CN">
<head>
  <meta charset="utf-8" />
  <meta name="viewport" content="width=device-width,initial-scale=1" />
  <title>代肝下单菜单</title>
  <style>
    /* 主题变量（会被 JS 动态切换） */
    :root{
      --bg:#f6f7fb;--card:#ffffff;--muted:#6b7280;--accent:#10b981;--border:#e6e9ef;
    }
    /* 基本重置和排版 */
    *{box-sizing:border-box}body{font-family:system-ui,-apple-system,Segoe UI,Roboto,'Helvetica Neue',Arial;margin:0;background:var(--bg);color:#0f172a}
    .wrap{max-width:1280px;margin:28px auto;padding:18px}
    .panel{background:var(--card);border:1px solid var(--border);border-radius:12px;box-shadow:0 6px 18px rgba(12,23,48,0.06);overflow:hidden;position:relative}
    .grid{display:grid;grid-template-columns:360px 1fr;gap:0}
    @media (max-width:880px){.grid{grid-template-columns:1fr}.aside{order:2} .main{order:1}}
    .aside{border-right:1px solid var(--border);padding:18px;height:640px;overflow:auto;position:relative;z-index:30} /* Eliya备注：侧栏整体层级提高，确保展开层在新增按钮之上 */
    .main{padding:20px}
    h1{font-size:18px;margin:0 0 6px}
    p.lead{margin:0 0 12px;color:var(--muted);font-size:13px}
    .top-controls{display:flex;gap:8px;align-items:center;margin-bottom:10px}
    .theme-chooser{display:flex;gap:6px;align-items:center}
    .theme-btn{width:28px;height:20px;border-radius:6px;border:1px solid var(--border);cursor:pointer}
    .search{display:flex;gap:8px;margin-bottom:12px}
    .search input{flex:1;padding:10px;border:1px solid var(--border);border-radius:8px}
    /* 游戏单元：改为块级容器，内部一行用于 handle/card/menu，服务列表保持宽度 100% 在下方显示 */
    .game{border-radius:10px;margin-bottom:8px;background:transparent;position:relative;display:block}
    .game-row{display:flex;align-items:stretch}
    /* 左侧拖拽把手 */
    .handle{width:40px;display:flex;align-items:center;justify-content:center;cursor:grab;padding:6px}
    .handle:active{cursor:grabbing}
    .handle .bar{width:16px;height:2px;background:var(--muted);margin:2px 0;border-radius:2px}
    /* 卡片主体 */
    .game-card{flex:1;border-radius:10px;display:flex;align-items:center;justify-content:space-between;padding:12px;border:1px solid var(--border);background:linear-gradient(180deg,#fff,#fff);cursor:default}
    .game-card:hover{box-shadow:0 4px 12px rgba(16,185,129,0.06);border-color:var(--border)}
    .meta{font-size:18px;color:#0f172a}
    .tag{font-size:13px;color:var(--muted)}
    /* 三点菜单区域（右下） */
    .more-wrap{position:relative;margin-left:8px;display:flex;align-items:center;padding-bottom:0}
    .more-btn{width:34px;height:34px;border-radius:6px;border:1px solid var(--border);background:#fff;display:flex;align-items:center;justify-content:center;cursor:pointer}
    .dot{width:4px;height:4px;background:var(--muted);border-radius:50%;margin:1px 0}
    .menu{position:absolute;right:0;bottom:40px;background:#fff;border:1px solid var(--border);border-radius:8px;box-shadow:0 8px 24px rgba(2,6,23,0.08);overflow:hidden;display:none;z-index:20}
    .menu button{display:block;padding:8px 12px;border:none;background:transparent;width:100%;text-align:left;cursor:pointer}
    .menu button:hover{background:#f6f9ff}
    /* 服务列表：宽度 100%，在卡片下方 */
    .services{padding:8px;display:none;width:100%}
    .service{padding:8px;border-radius:8px;border:1px solid var(--border);margin-bottom:8px;cursor:pointer;background:#fff}
    .service:hover{transform:translateY(-2px);box-shadow:0 6px 18px rgba(2,6,23,0.04)}
    /* 代肝种类（服务标题）字号：与游戏品类互换为更小字号 */
    .svc-title{font-size:13px}
    /* 详情区 */
    .right-title{display:flex;justify-content:space-between;align-items:flex-start}
    .price-grid{display:grid;grid-template-columns:repeat(auto-fit,minmax(200px,1fr));gap:12px;margin-top:14px}
    .price-card{padding:12px;border-radius:10px;border:1px solid var(--border);background:linear-gradient(180deg,#fff,#fbfdff)}
    .pay-list{margin:0;padding-left:18px}
    .muted{color:var(--muted);font-size:13px}
    .btn{padding:8px 12px;border-radius:8px;border:1px solid var(--border);background:transparent;cursor:pointer}
    .btn-primary{background:var(--accent);color:#fff;border:none}
    .footer{padding:12px;border-top:1px solid var(--border);font-size:13px;color:var(--muted);display:flex;justify-content:space-between;align-items:center}
    .note{font-size:13px;color:var(--muted);background:#f8fafc;padding:10px;border-radius:8px;border:1px dashed var(--border)}
    .contact{font-weight:600}
    .copy-ok{display:inline-block;background:#ecfdf5;color:#065f46;padding:6px 8px;border-radius:6px;font-size:12px;margin-left:8px}
    .hidden{display:none}
    /* Eliya备注：展开收起的平滑过渡（0.1秒） */
    .smooth-toggle{overflow:hidden;transition:max-height 0.1s ease, opacity 0.1s ease;will-change:max-height,opacity}
    /* 支付切换与二维码面板 */
    .pay-toggle{display:flex;gap:8px;margin:8px 0}
    .pill{padding:6px 12px;border-radius:999px;border:1px solid var(--border);background:#fff;cursor:pointer}
    .pill.active{background:var(--accent);color:#fff;border-color:var(--accent)}
    .qr-panel{margin-top:10px;padding:12px;border-radius:10px;border:1px solid var(--border);background:linear-gradient(180deg,#e8fff4,#ffffff)}
    .qr-header{font-weight:600;margin-bottom:8px}
    .qr-box{display:flex;align-items:center;gap:12px}
    #payQrImg{width:180px;border-radius:6px;box-shadow:0 4px 12px rgba(2,6,23,0.08);transition:opacity .3s}
    .fade-out{opacity:0}
    .fade-in{opacity:1}
    /* 支付宝样式：蓝色渐变浅 50%（#8ABBFF -> #FFFFFF） */
    .qr-panel.alipay{background:linear-gradient(180deg,#8ABBFF,#FFFFFF);border-color:var(--border)}
    /* 新增按钮（品类总框右下角） */
    /* 新增按钮固定在外层 panel 的右下角，避免被左侧 .aside 覆盖 */
    .add-category{position:absolute;right:16px;bottom:16px;width:48px;height:48px;border-radius:12px;background:var(--accent);color:#fff;display:flex;align-items:center;justify-content:center;font-size:28px;cursor:pointer;border:none;box-shadow:0 8px 20px rgba(16,185,129,0.18);z-index:20}
    /* 模态框 */
    .modal-backdrop{position:fixed;inset:0;background:rgba(2,6,23,0.45);display:none;align-items:center;justify-content:center;z-index:60}
    .modal{width:680px;max-width:95%;background:#fff;/* Eliya备注：模态框整体方框圆角在这里的 border-radius；边框颜色在这里的 border 的颜色变量 */border-radius:12px;padding:16px;border:1px solid var(--border)} 
    .form-row{display:flex;gap:8px;margin-bottom:8px}
    .form-row input,.form-row textarea{flex:1;padding:8px;border:1px solid var(--border);/* Eliya备注：输入框边框颜色在这里的 border；输入框圆角在这里的 border-radius */border-radius:8px}
    .small{font-size:12px;color:var(--muted)}
    .draggable-ghost{opacity:0.6;border:2px dashed #cbd5e1;background:linear-gradient(180deg,#fff,#fff)}    
    
    /* 黑色主题覆盖：去掉渐变，统一改为靠内偏灰色的纯底色（不影响二维码面板） */
    html[data-theme="black"] body{color:#f8fafc}
    html[data-theme="black"] .panel,
    html[data-theme="black"] .aside,
    html[data-theme="black"] .menu,
    html[data-theme="black"] .service,
    html[data-theme="black"] .price-card,
    html[data-theme="black"] .btn,
    html[data-theme="black"] .footer,
    html[data-theme="black"] .note,
    html[data-theme="black"] .modal,
    html[data-theme="black"] .pill,
    html[data-theme="black"] .more-btn,
    html[data-theme="black"] .search input,
    html[data-theme="black"] .form-row input,
    html[data-theme="black"] .form-row textarea,
    html[data-theme="black"] .svc-row,
    html[data-theme="black"] .game-card{
      background: #2f3747 !important;
      color:#f8fafc !important;
      border: 1px solid #3b4458 !important; /* 黑色主题下的游戏品类细边框，便于区分边界 */
    }
    /* 黑色主题：游戏品类文字与提示为浅色 */
    html[data-theme="black"] .tag,
    html[data-theme="black"] .muted,
    html[data-theme="black"] .toggleIndicator{
      color:#e5e7eb !important;
    }
  </style>
</head>
<body>
  <div class="wrap">
    <div class="panel">
      <div style="padding:12px;display:flex;justify-content:space-between;align-items:center">
        <div>
          <h1 style="margin:0">代肝菜单</h1>
          <div class="small muted">选择游戏 → 展开项目 → 查看报价与联系方式</div>
        </div>

        <!-- 主题选择器：切换页面主题颜色 -->
        <div class="top-controls">
          <div class="theme-chooser small muted">主题：</div>
          <div id="themes" class="theme-chooser" aria-hidden="false">
            <button class="theme-btn" title="黑色" data-theme="black" style="background:#0f172a"></button>
            <button class="theme-btn" title="白色" data-theme="white" style="background:#ffffff;border:1px solid #ddd"></button>
            <button class="theme-btn" title="浅红色" data-theme="pink" style="background:#ffefef"></button>
            <button class="theme-btn" title="黄绿色" data-theme="lime" style="background:#e6ffdb"></button>
            <button class="theme-btn" title="橙色" data-theme="orange" style="background:#fff4e6"></button>
          </div>
          <!-- 文件保存/导入按钮（顶部工具栏，不改变现有布局） -->
          <div class="file-io" style="display:flex;gap:8px">
            <button id="btnSaveFile" class="btn btn-primary" title="保存到 JSON 文件">保存到文件</button>
            <button id="btnLoadFile" class="btn" title="从 JSON 文件导入">从文件导入</button>
          </div>
        </div>
      </div>

      <div class="grid">
        <aside class="aside">
          <div class="search">
            <input id="q" placeholder="搜索游戏或服务（示例：段位、素材）" />
            <button id="clear" class="btn">清除</button>
          </div>

          <!-- 游戏列表容器（可拖拽排序） -->
          <div id="games" aria-live="polite"></div>

          <!-- 新增品类按钮已移至外层 panel 的右下角，避免遮挡滚动条 -->

          <!-- Eliya备注：提示语暂时隐藏 -->
          <div style="margin-top:12px;font-size:13px;color:var(--muted);display:none">
            提示：点击某个服务后右侧会显示详细价格与下单方式。你可以把示例数据替换为真实商品与价格。
          </div>
        </aside>

        <main class="main">
          <div id="detailPlaceholder">
            <div class="note">请选择左侧的游戏与服务查看详情</div>
          </div>

          <div id="detailPanel" class="hidden">
            <div class="right-title">
              <div>
                <div id="svcTitle" style="font-size:20px;font-weight:700"></div>
                <div id="svcMeta" class="muted" style="margin-top:6px"></div>
              </div>
              <div id="contactBlock" class="muted">联系方式：<span id="contactVal" class="contact"></span></div>
            </div>

            <div class="price-grid" style="margin-top:16px">
              <div style="min-width:240px">
                <div style="font-weight:600;margin-bottom:8px">价格选项</div>
                <div id="prices"></div>
              </div>
              <div>
                <div style="font-weight:600;margin-bottom:8px">支付方式 & 下单</div>
                <div class="muted">支持：</div>
                <ul id="pays" class="pay-list"></ul>

                <!-- 支付切换与二维码展示 -->
                <div id="payToggle" class="pay-toggle" aria-label="选择支付方式">
                  <button type="button" class="pill active" data-pay="wechat">微信</button>
                  <button type="button" class="pill" data-pay="alipay">支付宝</button>
                </div>
                <div id="qrPanel" class="qr-panel">
                  <div class="qr-header">推荐使用<span id="qrTitlePay">微信</span>支付</div>
                  <div class="qr-box">
                    <img id="payQrImg" src="微信收款码.png" alt="收款码" />
                    <div class="small muted">请使用对应 App 扫码付款</div>
                  </div>
                </div>

                <div style="margin-top:12px;display:flex;gap:8px">
                  <button id="copyBtn" class="btn btn-primary">复制联系方式</button>
                  <button id="payGuide" class="btn">查看付款说明</button>
                </div>

                <div style="margin-top:12px;font-size:13px;color:var(--muted)">
                  下单示例流程：
                  <ol style="padding-left:18px;margin-top:6px">
                    <li>复制联系方式并添加客服/发工单</li>
                    <li>说明游戏、服务器、当前段位与目标、期望时限</li>
                    <li>付款并截图，提供订单编号</li>
                    <li>客服确认后安排代练并提供进度截图</li>
                  </ol>
                </div>
              </div>
            </div>

            <div style="margin-top:14px" class="note">
              安全与协议（示例）：代练过程中不承担账号因违反游戏条款被封的全部责任，代练前请做好账号备份并设置合理权限。
            </div>
          </div>
        </main>
      </div>

      <!-- 新增品类按钮（外框右下角，不遮挡左侧滚动条） -->
      <button id="addCategoryBtn" class="add-category" title="新增品类">+</button>

      <div class="footer">
        <div>说明：这里是说明还不知道说什么。</div>
        <div class="small muted"> </div>
      </div>
    </div>
  </div>

  <!-- 模态：新增/编辑品类（与之前新增界面一致） -->
   <style id=\"modal-fixes\">#editModal, #modal, .modal, .modal-content, .modal-body { max-height: 80vh; overflow-y: auto; } #editModal input, #editModal textarea, #editModal select, #modal input, #modal textarea, #modal select, .modal input, .modal textarea, .modal select { border-radius: 10px !important; /* Eliya备注：新建/编辑代肝项目里输入框/下拉框的圆角在这里，改 10px 即可 */ } #editModal .box, #editModal .card, #editModal .service-row, #modal .box, #modal .card, #modal .service-row, .modal .box, .modal .card, .modal .service-row { border-radius: 10px; /* Eliya备注：模态内的卡片/服务项目容器圆角在这里，改 10px */ overflow: hidden; }</style>
  <div id="modalBack" class="modal-backdrop" role="dialog" aria-hidden="true">
    <div class="modal" role="document" aria-modal="true">
      <h3 id="modalTitle">新增品类</h3>
      <div class="form-row"><input id="inpName" placeholder="游戏名称（例：英雄联盟）" /></div>
      <div class="form-row"><input id="inpTag" placeholder="分类标签（例：MOBA）" /></div>
      
      <div id="servicesContainer" style="margin:10px 0 0 0">
        <!-- 在此处动态插入多个服务项，每一项包含：标题、描述、价格标签、价格，以及删除按钮 -->
      </div>

      <div class="form-row">
        <select id="inpPayments" title="选择支付方式">
          <option value="wechat">微信</option>
          <option value="alipay">支付宝</option>
          <option value="both" selected>微信和支付宝</option>
        </select>
      </div>
      <div class="form-row"><input id="inpContactType" placeholder="联系方式类型（例：微信）" /><input id="inpContactValue" placeholder="联系方式值（例：wx123）" /></div>

      <div style="display:flex;gap:8px;align-items:center;justify-content:space-between;margin-top:12px">
        <button id="btnAddService" class="btn">+新增服务</button>
        <div style="display:flex;gap:8px">
          <button id="modalCancel" class="btn">取消</button>
          <button id="modalSave" class="btn btn-primary">保存</button>
        </div>
      </div>
    </div>
  </div>

<script>
/* ------------------
   代码注释（给代码小白看的说明）：
   - localStorageKey: 页面会把你的 DATA 和 主题保存在浏览器 localStorage（本地存储），刷新或关闭浏览器再打开可以保留修改。
   - saveData(): 每次新增/编辑/删除/排序后会调用它把最新的 DATA 存入 localStorage。
   - loadData(): 页面加载时会尝试从 localStorage 读取数据；如果没有会加载示例数据。
   - renderList(): 渲染左侧的游戏列表（包含拖拽把手和三点菜单）。
   - openModal() / closeModal(): 管理新增/编辑模态窗口。
  ------------------ */

const localStorageKey = 'boost_DATA_v1';
const themeKey = 'boost_theme_v1';

/* 默认示例数据（如果 localStorage 没数据就使用这些） */
const DEFAULT_DATA = [
  { id:'lol', name:'英雄联盟', tag:'MOBA', services:[
    { id:'lol-1', title:'段位代冲（保底）', desc:'从当前段位冲到目标段位，含每日进度截图与战绩记录。', priceOptions:[{label:'青铜→白银',price:40},{label:'白银→黄金',price:90},{label:'黄金→铂金',price:180}], paymentMethods:['微信','支付宝'], contact:{type:'微信',value:'wx123_boost'}},
    { id:'lol-2', title:'代练教学（陪练式）', desc:'边代练边讲解，适合想学习技巧的玩家。', priceOptions:[{label:'1小时',price:60},{label:'包10小时',price:520}], paymentMethods:['微信','支付宝'], contact:{type:'QQ',value:'123456789'}}
  ]},
  { id:'cs2', name:'CS2 (反恐精英2)', tag:'射击', services:[
    { id:'cs2-1', title:'段位代练（匹配）', desc:'按场次计费，保留比赛录像供客户核验。', priceOptions:[{label:'单场',price:30},{label:'5场包',price:140}], paymentMethods:['微信','PayPal'], contact:{type:'Discord',value:'discord.gg/yourroom'}}
  ]},
  { id:'genshin', name:'原神', tag:'开放世界', services:[
    { id:'genshin-1', title:'周常/素材代刷', desc:'按周常/素材种类与数量计价，安全操作。', priceOptions:[{label:'单次周常',price:25},{label:'素材刷x10',price:120}], paymentMethods:['微信','支付宝'], contact:{type:'微信',value:'wx_genshin_boost'}}
  ]},
  { id:'dota2', name:'DOTA2', tag:'MOBA', services:[
    { id:'dota-1', title:'段位代练/段位保级', desc:'保级/冲分服务，提供进度截图与战绩。', priceOptions:[{label:'单场',price:35},{label:'包10场',price:300}], paymentMethods:['微信','支付宝','PayPal'], contact:{type:'工单',value:'support@yourstore.com'}}
  ]}
];

// 尝试从 localStorage 读取，如果没有则使用默认
let DATA = loadData();

// DOM 引用
const gamesEl = document.getElementById('games');
const qEl = document.getElementById('q');
const clearBtn = document.getElementById('clear');
const detailPanel = document.getElementById('detailPanel');
const detailPlaceholder = document.getElementById('detailPlaceholder');
const svcTitle = document.getElementById('svcTitle');
const svcMeta = document.getElementById('svcMeta');
const contactVal = document.getElementById('contactVal');
const pricesEl = document.getElementById('prices');
const paysEl = document.getElementById('pays');
const copyBtn = document.getElementById('copyBtn');
const payGuide = document.getElementById('payGuide');
const addCategoryBtn = document.getElementById('addCategoryBtn');
const modalBack = document.getElementById('modalBack');
const modalTitle = document.getElementById('modalTitle');
const modalSave = document.getElementById('modalSave');
const modalCancel = document.getElementById('modalCancel');
const btnSaveFile = document.getElementById('btnSaveFile');
const btnLoadFile = document.getElementById('btnLoadFile');

// modal inputs（移除单一服务输入，改为多服务容器）
const inpName = document.getElementById('inpName');
const inpTag = document.getElementById('inpTag');
const servicesContainer = document.getElementById('servicesContainer');
const btnAddService = document.getElementById('btnAddService');
const inpPayments = document.getElementById('inpPayments');
const inpContactType = document.getElementById('inpContactType');
const inpContactValue = document.getElementById('inpContactValue');
// 支付切换与二维码相关元素
const payToggle = document.getElementById('payToggle');
const qrPanel = document.getElementById('qrPanel');
const payQrImg = document.getElementById('payQrImg');
const qrTitlePay = document.getElementById('qrTitlePay');

let currentService = null; // 当前选中的服务（用于详情区显示与复制）

// --- 动态服务行生成 ---
function makeServiceRow(svc = { title: '', desc: '', priceOptions: [{ label: '', price: 0 }] }) {
  const row = document.createElement('div');
  row.className = 'svc-row';
  row.style.border = '1px solid var(--border)'; // Eliya备注：服务项方框的边框颜色在这里，修改 var(--border)
  row.style.borderRadius = '10px'; // Eliya备注：服务项方框圆角度数在这里，改 10px
  row.style.padding = '10px';
  row.style.margin = '10px 0';
  row.style.background = 'var(--card)'; // Eliya备注：服务项方框背景色在这里，修改 var(--card)

  const title = document.createElement('input');
  title.placeholder = '服务标题';
  title.value = svc.title || '';
  title.style.marginBottom = '8px';
  title.style.width = '100%';

  const desc = document.createElement('input');
  desc.placeholder = '服务描述';
  desc.value = svc.desc || '';
  desc.style.marginBottom = '8px';
  desc.style.width = '100%';

  const prrow = document.createElement('div');
  prrow.style.display = 'flex';
  prrow.style.gap = '8px';
  prrow.style.marginBottom = '8px';

  const priceLabel = document.createElement('input');
  priceLabel.placeholder = '价格或选项标签（例：白银→黄金）';
  priceLabel.value = (svc.priceOptions && svc.priceOptions[0] && svc.priceOptions[0].label) || '';
  priceLabel.style.flex = '1';

  const priceValue = document.createElement('input');
  priceValue.placeholder = '价格（数字）';
  priceValue.type = 'number';
  priceValue.value = (svc.priceOptions && svc.priceOptions[0] && svc.priceOptions[0].price) || 0;
  priceValue.style.width = '140px';

  prrow.appendChild(priceLabel);
  prrow.appendChild(priceValue);

  const del = document.createElement('button');
  del.className = 'btn';
  del.textContent = '删除此服务';
  del.style.color = '#b91c1c';
  del.style.borderColor = '#ef4444';
  del.onclick = () => {
    row.remove();
  };

  row.appendChild(title);
  row.appendChild(desc);
  row.appendChild(prrow);
  row.appendChild(del);

  // 存储引用，便于采集
  row._refs = { title, desc, priceLabel, priceValue };
  return row;
}

// --- 从UI采集多个服务 ---
function getServicesFromUI(gameId) {
  const rows = Array.from(servicesContainer.querySelectorAll('.svc-row'));
  // 下拉选择：wechat / alipay / both
  const sel = inpPayments.value || 'both';
  const pays = sel === 'wechat' ? ['微信'] : (sel === 'alipay' ? ['支付宝'] : ['微信','支付宝']);
  const ctype = inpContactType.value.trim();
  const cval = inpContactValue.value.trim();
  return rows.map((row, idx) => {
    const { title, desc, priceLabel, priceValue } = row._refs || {};
    const t = (title && title.value.trim()) || '未命名服务';
    const d = (desc && desc.value.trim()) || '';
    const pl = (priceLabel && priceLabel.value.trim()) || '单次';
    const pv = Number((priceValue && priceValue.value) || 0) || 0;
    return {
      id: `${gameId}-${idx + 1}`,
      title: t,
      desc: d,
      priceOptions: [{ label: pl, price: pv }],
      paymentMethods: pays,
      contact: { type: ctype || '微信', value: cval || '' }
    };
  });
}

/* ------------------ 本地存储工具函数 ------------------ */
function saveData(){
  try{
    localStorage.setItem(localStorageKey, JSON.stringify(DATA));
    // 保存当前主题
    const theme = document.documentElement.getAttribute('data-theme') || 'white';
    localStorage.setItem(themeKey, theme);
  }catch(e){
    console.error('保存 localStorage 失败', e);
  }
}
function loadData(){
  try{
    const raw = localStorage.getItem(localStorageKey);
    if(raw){
      return JSON.parse(raw);
    }
  }catch(e){
    console.error('读取 localStorage 失败', e);
  }
  return JSON.parse(JSON.stringify(DEFAULT_DATA));
}

/* ------------------ 文件保存/导入（优先使用文件系统访问 API） ------------------ */
function serializeBackup(){
  const theme = document.documentElement.getAttribute('data-theme') || 'white';
  // 直接使用内存中的 DATA（已包含你在页面上的所有修改）
  return { data: DATA, theme };
}

async function saveToFile(){
  const payload = JSON.stringify(serializeBackup(), null, 2);
  try{
    if('showSaveFilePicker' in window){
      const handle = await window.showSaveFilePicker({
        suggestedName: '菜单2-数据备份.json',
        types: [{ description: 'JSON 文件', accept: { 'application/json': ['.json'] } }]
      });
      const writable = await handle.createWritable();
      await writable.write(payload);
      await writable.close();
      alert('已保存到文件。');
    }else{
      // 回退：触发下载到本地
      const blob = new Blob([payload], { type: 'application/json' });
      const a = document.createElement('a');
      a.href = URL.createObjectURL(blob);
      a.download = '菜单2-数据备份.json';
      document.body.appendChild(a);
      a.click();
      URL.revokeObjectURL(a.href);
      a.remove();
      alert('已生成下载文件，请选择保存到目标文件夹。');
    }
  }catch(e){
    console.error('保存失败', e);
    alert('保存失败：'+ e.message);
  }
}

async function loadFromFile(){
  try{
    if('showOpenFilePicker' in window){
      const [handle] = await window.showOpenFilePicker({
        types: [{ description: 'JSON 文件', accept: { 'application/json': ['.json'] } }]
      });
      const file = await handle.getFile();
      const text = await file.text();
      applyBackupJSON(text);
    }else{
      // 回退：使用 <input type="file"> 选择文件
      const input = document.createElement('input');
      input.type = 'file';
      input.accept = '.json,application/json';
      input.onchange = async ()=>{
        const file = input.files && input.files[0];
        if(!file) return;
        const text = await file.text();
        applyBackupJSON(text);
      };
      input.click();
    }
  }catch(e){
    console.error('导入失败', e);
    alert('导入失败：'+ e.message);
  }
}

function applyBackupJSON(text){
  try{
    const obj = JSON.parse(text);
    if(!obj || !obj.data || !Array.isArray(obj.data)) throw new Error('文件格式不正确');
    DATA = obj.data;
    // 保存到 localStorage 作为冗余
    saveData();
    // 恢复主题（如有）
    applyTheme(obj.theme || 'white');
    // 重新渲染左侧列表
    renderList(qEl.value || '');
    // 回到占位区
  /* Eliya备注：隐藏右侧详情改为平滑动画 */
  smoothHide(detailPanel);
  detailPlaceholder.classList.remove('hidden');
    alert('导入成功，已恢复数据');
  }catch(e){
    console.error('文件解析失败', e);
    alert('文件解析失败：'+ e.message);
  }
}

/* ------------------ 渲染函数：把 DATA 渲染到左侧列表 ------------------ */
function renderList(filter='') {
  gamesEl.innerHTML = '';
  const q = filter.trim().toLowerCase();
  const filtered = q ? DATA.map(g=>({...g, services:g.services.filter(s=>s.title.toLowerCase().includes(q)||s.desc.toLowerCase().includes(q)||g.name.toLowerCase().includes(q))})).filter(g=>g.services.length) : DATA;
  if(filtered.length===0){
    gamesEl.innerHTML = '<div style="color:var(--muted);font-size:13px;padding:10px">未找到匹配项，试试更宽泛的关键词。</div>';
    return;
  }

  filtered.forEach((game, gameIndex)=>{
    const wrap = document.createElement('div');
    wrap.className = 'game';
    wrap.dataset.gameId = game.id;

    // 内部一行：handle + card + moreWrap
    const row = document.createElement('div');
    row.className = 'game-row';

    // ===== 左侧拖拽把手（3 条横线） =====
    const handle = document.createElement('div');
    handle.className = 'handle';
    handle.title = '按住拖动排序';
    handle.innerHTML = '<div><div class=\"bar\"></div><div class=\"bar\"></div><div class=\"bar\"></div></div>';
    row.appendChild(handle);

    // ===== 卡片主体（游戏名 + 标签 + toggleIndicator） =====
    const card = document.createElement('div');
    card.className = 'game-card';
    card.innerHTML = `<div style="display:flex;flex-direction:column;gap:4px">
                        <div style="font-weight:600" class="meta">${game.name}</div>
                        <div class="tag" style="font-size:13px;color:var(--muted)">${game.tag}</div>
                      </div>
                      <div class="toggleIndicator" style="font-size:20px;color:var(--muted);padding-left:8px">+</div>`;
    row.appendChild(card);

    // ===== 右下三点菜单（更多操作：编辑/删除） =====
    const moreWrap = document.createElement('div');
    moreWrap.className = 'more-wrap';
    moreWrap.innerHTML = `<div class="more-btn" title="更多操作" aria-haspopup="true" aria-expanded="false" role="button">
                            <div style="display:flex;flex-direction:column;align-items:center;justify-content:center">
                              <div class="dot"></div><div class="dot"></div><div class="dot"></div>
                            </div>
                          </div>
                          <div class="menu" role="menu">
                            <button class="edit">编辑</button>
                            <button class="del" style="color:#b91c1c">删除</button>
                          </div>`;
    row.appendChild(moreWrap);

    // 把这一行加入 wrap
    wrap.appendChild(row);

    // ===== 服务列表（默认隐藏，点击卡片时切换显示） =====
    const srvWrap = document.createElement('div');
    srvWrap.className = 'services';
    srvWrap.style.display = 'none';
    srvWrap.setAttribute('aria-hidden','true');
    game.services.forEach(svc=>{
      const sEl = document.createElement('div');
      sEl.className = 'service';
      // Eliya：服务标题增加 .svc-title 类，以便与游戏品类字号互换（更小）
      sEl.innerHTML = `<div class="svc-title" style="font-weight:600">${svc.title}</div><div class="muted" style="margin-top:6px">${svc.desc}</div>`;
      sEl.addEventListener('click',()=>showService(svc,game));
      srvWrap.appendChild(sEl);
    });
    wrap.appendChild(srvWrap);

    // =========== 事件绑定 ===========

    // 1) 切换展开/收起服务列表（点击卡片时）
    card.addEventListener('click',()=>{
      const open = srvWrap.style.display === 'block';
      // 折叠其它已打开的服务（这里只影响可见的服务区域）
      document.querySelectorAll('.game .services').forEach(el=>{ el.style.display='none'; el.setAttribute('aria-hidden','true'); });
      document.querySelectorAll('.game .toggleIndicator').forEach(el=>el.textContent='+');
      srvWrap.style.display = open ? 'none' : 'block';
      srvWrap.setAttribute('aria-hidden', open ? 'true' : 'false');
      // 切换当前指示器为 + 或 -
      card.querySelector('.toggleIndicator').textContent = open ? '+' : '-';
    });

    // 2) 三点按钮：展开/收起菜单
    const moreBtn = moreWrap.querySelector('.more-btn');
    const menu = moreWrap.querySelector('.menu');
    moreBtn.addEventListener('click',(e)=>{
      e.stopPropagation();
      const expanded = menu.style.display === 'block';
      // 先关闭页面上其它菜单
      document.querySelectorAll('.more-wrap .menu').forEach(m=>{ if(m!==menu) m.style.display='';});
      menu.style.display = expanded ? '' : 'block';
    });
    // 点击页面任意处关闭菜单
    document.addEventListener('click',()=>{
      document.querySelectorAll('.more-wrap .menu').forEach(m=>m.style.display='');
    });

    // 3) 编辑按钮（打开 modal，并填入数据，供修改）
    moreWrap.querySelector('.edit').addEventListener('click',(e)=>{
      e.stopPropagation();
      openModal('edit', game, gameIndex);
      menu.style.display='';
    });

    // 4) 删除按钮（删除该游戏品类）
    moreWrap.querySelector('.del').addEventListener('click',(e)=>{
      e.stopPropagation();
      if(confirm('确认删除此品类？该操作不可恢复。')){
        // 从 DATA 中删除
        DATA = DATA.filter(d=>d.id !== game.id);
        saveData();
        renderList(qEl.value);
        // 若当前详情区显示的服务属于被删除游戏，隐藏详情区
        if(currentService && currentService.game && currentService.game.id === game.id){
  /* Eliya备注：隐藏右侧详情改为平滑动画 */
  smoothHide(detailPanel);
  detailPlaceholder.classList.remove('hidden');
        }
      }
      menu.style.display='';
    });

    /* --------- 拖拽相关（只在按住左侧把手时允许拖动） --------- */
    handle.addEventListener('mousedown', (ev)=>{
      // 设置可拖拽
      wrap.setAttribute('draggable','true');
      wrap.classList.add('draggable-ghost');
    });
    handle.addEventListener('mouseup', ()=>{
      wrap.removeAttribute('draggable');
      wrap.classList.remove('draggable-ghost');
    });
    handle.addEventListener('mouseleave', ()=>{
      wrap.removeAttribute('draggable');
      wrap.classList.remove('draggable-ghost');
    });

    wrap.addEventListener('dragstart', (e)=>{
      e.dataTransfer.setData('text/plain', game.id);
    });

    wrap.addEventListener('dragover', (e)=>{
      e.preventDefault();
      wrap.style.outline = '2px dashed #cbd5e1';
    });
    wrap.addEventListener('dragleave', ()=>{ wrap.style.outline=''; });
    wrap.addEventListener('drop', (e)=>{
      e.preventDefault();
      wrap.style.outline='';
      const srcId = e.dataTransfer.getData('text/plain');
      const dstId = wrap.dataset.gameId;
      if(!srcId || srcId === dstId) return;
      const srcIndex = DATA.findIndex(d=>d.id===srcId);
      const dstIndex = DATA.findIndex(d=>d.id===dstId);
      if(srcIndex<0||dstIndex<0) return;
      const [item] = DATA.splice(srcIndex,1);
      DATA.splice(dstIndex,0,item);
      saveData();
      renderList(qEl.value);
    });

    // 5) 阻止点击更多按钮和编辑时触发折叠等
    moreWrap.addEventListener('click',(e)=>e.stopPropagation());

    gamesEl.appendChild(wrap);
  });
}

/* ------------------ 显示服务详情（右侧面板） ------------------ */
function showService(svc, game){
  currentService = { ...svc, game };
  /* Eliya备注：显示右侧详情改为平滑动画（0.1s） */
  detailPlaceholder.classList.add('hidden');
  smoothShow(detailPanel);
  svcTitle.textContent = svc.title;
  svcMeta.textContent = `${game.name} · ${svc.desc}`;
  contactVal.textContent = `${svc.contact.type}: ${svc.contact.value}`;

  pricesEl.innerHTML = '';
  svc.priceOptions.forEach(p=>{
    const pc = document.createElement('div');
    pc.className = 'price-card';
    pc.innerHTML = `<div style="font-weight:600">${p.label}</div><div style="margin-top:6px;font-size:18px;font-weight:700">¥${p.price}</div>`;
    pricesEl.appendChild(pc);
  });

  paysEl.innerHTML = '';
  (svc.paymentMethods||[]).filter(m=> m !== 'QQ钱包').forEach(m=>{
    const li = document.createElement('li');
    li.textContent = m;
    paysEl.appendChild(li);
  });

  // 控制支付切换按钮显示与默认二维码
  const hasWeChat = (svc.paymentMethods||[]).some(m=>/微/.test(m));
  const hasAlipay = (svc.paymentMethods||[]).some(m=>/支/.test(m));
  if(payToggle && qrPanel){
    const weBtn = payToggle.querySelector('[data-pay="wechat"]');
    const aliBtn = payToggle.querySelector('[data-pay="alipay"]');
    if(weBtn) weBtn.style.display = hasWeChat ? '' : 'none';
    if(aliBtn) aliBtn.style.display = hasAlipay ? '' : 'none';
    qrPanel.style.display = (hasWeChat || hasAlipay) ? '' : 'none';
    if(hasWeChat){ switchPay('wechat'); }
    else if(hasAlipay){ switchPay('alipay'); }
  }

  // 已取消邮件下单按钮
}

/* 支付方式切换与二维码过渡 */
function switchPay(type){
  if(!payToggle || !payQrImg || !qrTitlePay) return;
  const label = type === 'wechat' ? '微信' : '支付宝';
  qrTitlePay.textContent = label;
  // 渐隐 → 切图 → 渐显
  payQrImg.classList.remove('fade-in');
  payQrImg.classList.add('fade-out');
  const nextSrc = type === 'wechat' ? '微信收款码.png' : '支付宝收款码.png';
  setTimeout(()=>{
    payQrImg.src = nextSrc;
    payQrImg.onload = ()=>{
      payQrImg.classList.remove('fade-out');
      payQrImg.classList.add('fade-in');
    };
  },150);
  // 按钮高亮
  payToggle.querySelectorAll('button').forEach(btn=>{
    btn.classList.toggle('active', btn.dataset.pay === type);
  });
  // 面板底色切换（支付宝为 #1677ff）
  if(qrPanel){
    qrPanel.classList.remove('alipay');
    if(type==='alipay'){
      qrPanel.classList.add('alipay');
    }
  }
}

payToggle && payToggle.addEventListener('click',(e)=>{
  const btn = e.target.closest('button');
  if(!btn) return;
  const pay = btn.dataset.pay;
  if(pay){ switchPay(pay); }
});

/* ------------------ 复制联系方式 ------------------ */
copyBtn.addEventListener('click',async ()=>{
  if(!currentService){alert('请先选一个服务');return;}
  const text = currentService.contact.value;
  try{
    await navigator.clipboard.writeText(text);
    copyBtn.textContent = '已复制';
    copyBtn.classList.add('copy-ok');
    setTimeout(()=>{copyBtn.textContent='复制联系方式'; copyBtn.classList.remove('copy-ok')},2000);
  }catch(e){
    prompt('请手动复制联系方式：', text);
  }
});

payGuide.addEventListener('click',()=>{
  alert('定金单尾款需提前找客服结清噢~');
});

clearBtn.addEventListener('click',()=>{ qEl.value=''; renderList(''); });
qEl.addEventListener('input',(e)=>renderList(e.target.value));

// 顶部文件保存/导入按钮事件
btnSaveFile && btnSaveFile.addEventListener('click', saveToFile);
btnLoadFile && btnLoadFile.addEventListener('click', loadFromFile);

/* ------------------ 模态：新增/编辑 品类 ------------------ */
function openModal(mode, game=null, gameIndex=null){
  modalBack.style.display = 'flex';
  modalBack.setAttribute('aria-hidden','false');

  // 重置
  servicesContainer.innerHTML = '';

  if(mode === 'edit' && game){
    modalTitle.textContent = '编辑品类';
    inpName.value = game.name;
    inpTag.value = game.tag || '';

    // 使用该品类第一个服务的支付与联系方式作为默认
    const baseSvc = game.services[0] || {};
    // 根据第一个服务的支付方式推断下拉默认值
    const pm = (baseSvc.paymentMethods||[]);
    if(pm.includes('微信') && pm.includes('支付宝')){ inpPayments.value = 'both'; }
    else if(pm.includes('支付宝')){ inpPayments.value = 'alipay'; }
    else { inpPayments.value = 'wechat'; }
    inpContactType.value = (baseSvc.contact && baseSvc.contact.type) || '';
    inpContactValue.value = (baseSvc.contact && baseSvc.contact.value) || '';

    // 渲染已有服务项
    (game.services||[]).forEach(s=>{
      servicesContainer.appendChild(makeServiceRow(s));
    });

    // 保存逻辑：收集多个服务项
    modalSave.onclick = ()=>{
      const updated = {
        id: game.id,
        name: inpName.value.trim() || game.name,
        tag: inpTag.value.trim() || game.tag,
        services: getServicesFromUI(game.id)
      };
      DATA[gameIndex] = updated;
      saveData();
      closeModal();
      renderList(qEl.value);
    };
  } else {
    modalTitle.textContent = '新增品类';
    inpName.value=''; inpTag.value='';
    inpPayments.value='both'; inpContactType.value=''; inpContactValue.value='';

    // 默认先添加一个空服务项
    servicesContainer.appendChild(makeServiceRow());

    modalSave.onclick = ()=>{
      const nid = 'g'+Date.now();
      const newGame = {
        id: nid,
        name: inpName.value.trim() || '新游戏',
        tag: inpTag.value.trim() || '',
        services: getServicesFromUI(nid)
      };
      DATA.push(newGame);
      saveData();
      closeModal();
      renderList(qEl.value);
    };
  }
}

// 绑定+新增服务按钮
btnAddService.addEventListener('click', ()=>{
  servicesContainer.appendChild(makeServiceRow());
});

modalCancel.addEventListener('click', closeModal);
modalBack.addEventListener('click',(e)=>{ if(e.target===modalBack) closeModal(); });

function closeModal(){
  modalBack.style.display='none';
  modalBack.setAttribute('aria-hidden','true');
}

/* 点击新增按钮打开 modal */
addCategoryBtn.addEventListener('click', ()=> openModal('new'));

/* ------------------ 主题切换（更换 CSS 变量并保存主题） ------------------ */
const themeButtons = document.querySelectorAll('[data-theme]');
themeButtons.forEach(btn=>{
  btn.addEventListener('click', ()=>{
    const t = btn.dataset.theme;
    applyTheme(t);
    saveData();
  });
});

function applyTheme(t){
  document.documentElement.setAttribute('data-theme', t);
  if(t==='black'){
    document.documentElement.style.setProperty('--bg','#0f172a');
    document.documentElement.style.setProperty('--card','#0b1220');
    document.documentElement.style.setProperty('--muted','#9ca3af');
    document.documentElement.style.setProperty('--accent','#22c55e');
    document.documentElement.style.setProperty('--border','#111827');
    document.body.style.color = '#e6eef6';
  } else if(t==='white'){
    document.documentElement.style.setProperty('--bg','#f6f7fb');
    document.documentElement.style.setProperty('--card','#ffffff');
    document.documentElement.style.setProperty('--muted','#6b7280');
    document.documentElement.style.setProperty('--accent','#10b981');
    document.documentElement.style.setProperty('--border','#e6e9ef');
    document.body.style.color = '#0f172a';
  } else if(t==='pink'){
    document.documentElement.style.setProperty('--bg','#fff3f4');
    document.documentElement.style.setProperty('--card','#fff');
    document.documentElement.style.setProperty('--muted','#6b7280');
    document.documentElement.style.setProperty('--accent','#fb7185');
    document.documentElement.style.setProperty('--border','#fdecef');
    document.body.style.color = '#0f172a';
  } else if(t==='lime'){
    document.documentElement.style.setProperty('--bg','#f7ffed');
    document.documentElement.style.setProperty('--card','#ffffff');
    document.documentElement.style.setProperty('--muted','#526057');
    document.documentElement.style.setProperty('--accent','#84cc16');
    document.documentElement.style.setProperty('--border','#eef9e6');
    document.body.style.color = '#0f172a';
  } else if(t==='orange'){
    document.documentElement.style.setProperty('--bg','#fff7ed');
    document.documentElement.style.setProperty('--card','#ffffff');
    document.documentElement.style.setProperty('--muted','#6b4f2a');
    document.documentElement.style.setProperty('--accent','#fb923c');
    document.documentElement.style.setProperty('--border','#fff1e6');
    document.body.style.color = '#0f172a';
  }
}

// 恢复上次保存的主题（如果有）
const savedTheme = localStorage.getItem(themeKey) || 'white';
applyTheme(savedTheme);

/* Eliya备注：展开/收起动画工具函数（0.1s，放在脚本内部，避免未定义错误） */
function smoothShow(el){
  if(!el) return;
  el.classList.remove('hidden');
  el.classList.add('smooth-toggle');
  el.style.maxHeight = '0px';
  el.style.opacity = '0';
  setTimeout(()=>{
    try{ el.style.maxHeight = el.scrollHeight + 'px'; el.style.opacity = '1'; }catch(e){}
  }, 0);
}
function smoothHide(el){
  if(!el) return;
  el.style.maxHeight = '0px';
  el.style.opacity = '0';
  setTimeout(()=>{
    el.classList.add('hidden');
    el.classList.remove('smooth-toggle');
    el.style.maxHeight = '';
    el.style.opacity = '';
  }, 110); // Eliya备注：略大于 0.1s，保证动画完成
}

/* ------------------ 初始渲染 ------------------ */
renderList();

// End of script
</script>

</body>
</html>
